/*
 * Copyright (C) 2006 Roman Krashanitsa
 *
 * @author Roman Krashanitsa
 *
 * This file is part of paparazzi.
 *
 * paparazzi is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * paparazzi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with paparazzi; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 *
 */

package pprz.components;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import net.jscience.math.MathFP;
import pprz.data_components.Message;
import pprz.data_components.events.DownlinkMessageEvent;
import pprz.data_components.events.DownlinkMessageEventListener;

public class Horizon extends Component 
implements DownlinkMessageEventListener, ActionListener {

	protected static final long serialVersionUID = 1L;
	protected int roll;
	protected int pitch;
	protected int ac;
//	protected int alt;
//	protected int vel;
//	protected Image dbImage;
	
	public Horizon() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	protected void initialize() {
		this.setMinimumSize(new Dimension(50, 50));
		this.setPreferredSize(new Dimension(50, 50));
		this.setSize(new Dimension(50, 50));
		ac=0;
		pitch=0; roll=45;
	}
	
	public void setAC(int ac)
	{
		this.ac=ac;
	}
	
	public void set(int r, int p, int a, int v)
	{ 
		pitch=p; roll=r;
		//alt=a; vel=v;
//		pitch=(int)MathFP.toLong(p);
		pitch=(pitch<180)?pitch:pitch-360;
		//alt=MathFP.toInt(v);
//		roll=(int)MathFP.toLong(v);
		//vel=MathFP.toInt(v);
//		drawBack();
		repaint(100);
	}
	
	//---FOR MOBILE DEVICE-----
	/*
	public void paint(Graphics g) {
		int width=this.getWidth();
		int height=this.getHeight();
		int d=Math.min(width,height);

		
		//clear drawing area
		g.setColor(new Color(100,100,100));
		Rectangle r=g.getClipBounds();
		//g.fillRect(g.getClipX(),g.getClipY(),g.getClipWidth(),g.getClipHeight());
		g.fillRect(r.x,r.y,r.width,r.height);
		//draw sky area
		g.setColor(new Color(0x6666FF));
		g.setColor(Color.blue);
		g.fillArc(0,0,d,d,roll,180);
		//draw ground area
		g.setColor(new Color(0x777744));
		g.setColor(Color.yellow);
		g.fillArc(0,0,d,d,roll+180,180);
		//draw pitch indicator
		if(pitch<90&&pitch>-90)
		{
			//for regular flight pitch
			g.setColor(new Color(0x9999FF));
			g.fillRect(d/2-10,d/6,20,d/2+d*pitch/90/3-d/6);
			g.setColor(new Color(0x666600));
			g.fillRect(d/2-10,d/2+d*pitch/90/3,20,d/2-d*pitch/90/3-d/6);
		}
		else
		{
			//for upside-down flight pitch
			pitch=(pitch>90)?pitch-180:pitch+180;
			g.setColor(new Color(0x666600));
			g.fillRect(d/2-10,d/6,20,d/2+d*pitch/90/3-d/6);
			g.setColor(new Color(0x9999FF));
			g.fillRect(d/2-10,d/2+d*pitch/90/3,20,d/2-d*pitch/90/3-d/6);
		}
		//cosmetics and accents
		g.setColor(Color.white);
		g.drawArc(0,0,d,d,0,360);
		
	}
	*/

	
	
	public void draw(Graphics g){
		System.out.println("Horizon::public void draw(Graphics g) called");
		int width=this.getWidth();
		int height=this.getHeight();
		int r=Math.min(width,height)/2;
		Graphics2D g2=(Graphics2D)g;
		int ticklen=Math.round(0.05f*r);
		int step=(r<50)?90:(r<100)?45:15;
		int ticks=360/step;
		FontMetrics fm=g2.getFontMetrics();
		int w=fm.stringWidth("180");;
		int h=fm.getHeight()-fm.getDescent();
		int cx=Math.round(0.1f*r+w); // max space required for text label
		int cy=Math.round(0.1f*r+h);
		 r=r-Math.max(cx,cy); // circle radius to fit the space and draw the label too
		double angle;
		String label;
	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		//draw sky area
		g2.setColor(new Color(0x99AAFF));
		
		g2.fillArc(cx,cy,2*r,2*r,(int)roll,180);
		//draw ground area
		g2.setColor(new Color(0xFFDD00));
		g2.fillArc(cx,cy,2*r,2*r,(int)roll+180,180);
		g2.setStroke(new BasicStroke(2));
		g2.setColor(Color.red);
		g2.drawLine(cx,r+cy,2*r+cx,r+cy);
		//draw pitch indicator
		if(pitch<90&&pitch>-90)
		{
			//for regular flight pitch
			g2.setColor(new Color(0x7788DD));
			g2.fillRect(r-r/5+cx,r/3+cy,r*2/5,r+2*r*pitch/90/3-r/3);
			g2.setColor(new Color(0xCCAA00));
			g2.fillRect(r-r/5+cx,r+2*r*pitch/90/3+cy,r*2/5,r-2*r*pitch/90/3-r/3);
		}
		else
		{
			//for upside-down flight pitch
			pitch=(pitch>90)?pitch-180:pitch+180;
			g2.setColor(new Color(0x666600));
			g2.fillRect(r-r/5+cx,r/3+cy,r*2/5,r+2*r*pitch/90/3-r/3);
			g2.setColor(new Color(0x9999FF));
			g2.fillRect(r-r/5+cx,r+2*r*pitch/90/3+cy,r*2/5,r-2*r*pitch/90/3-r/3);
		}
		//cosmetics and accents
		g2.setStroke(new BasicStroke(2));
		g2.setColor(Color.black);
		g2.drawArc(cx,cy,2*r,2*r,0,360);
		g2.setStroke(new BasicStroke(1));
		g2.drawRect(r-r/5+cx, r/3+cy, r*2/5, 4*r/3);
		//draw radial tickmarks&labels
		//right side
		for (int i=0; i<ticks/2; i++)
		{
			//draw labels
			angle=i*2*Math.PI/ticks+Math.PI/2.;
/*			if (i*360/ticks % step == 0)
			{
				label=String.valueOf(i*360/ticks);
				w=fm.stringWidth(label);
				g2.drawString(label, 
					(int)((r+0.7*ticklen)*Math.sin(angle)+r+cx-Math.abs(angle-Math.PI/2)*w/Math.PI),
				    (int)((r+0.7*ticklen)*Math.cos(angle)+r+cy+Math.abs(1-angle/Math.PI)*h));			
			}
*/			//draw tickmarks
			g2.drawLine((int)(r*Math.sin(angle))+r+cx,
					    (int)(r*Math.cos(angle))+r+cy,
					    (int)((r-ticklen)*Math.sin(angle))+r+cx,
					    (int)((r-ticklen)*Math.cos(angle))+r+cy );
		}
		//left side
		for (int i=0; i<ticks/2; i++)
		{
			angle=i*2*Math.PI/ticks+3*Math.PI/2;
			//draw labels
/*			if (i*360/ticks % step == 0) 
				{
					label=String.valueOf(i*360/ticks+180);
					w=fm.stringWidth(label);
					g2.drawString(label, 
								  (int)((r+0.7*ticklen)*Math.sin(angle)+r+cx-Math.abs(5*Math.PI/2-angle)*w/Math.PI),
								  (int)((r+0.7*ticklen)*Math.cos(angle)+r+cy+Math.abs(angle-Math.PI)*h/Math.PI));
				}
*/			//draw tickmarks
			g2.drawLine((int)(r*Math.sin(angle))+r+cx,
					    (int)(r*Math.cos(angle))+r+cy,
					    (int)((r-ticklen)*Math.sin(angle))+r+cx,
					    (int)((r-ticklen)*Math.cos(angle))+r+cy );
		}
		//draw pitch tickmarks&labels
		if(pitch<90&&pitch>-90)
		{
			//for regular flight pitch
			int y_ini=r+2*r*pitch/90/3+cy;
			int n=(r<50)?3:(r<100)?6:12;
			int y=y_ini+4*r/3/n;
			int i=-180/n;
			while (y<5*r/3+cy) {
				g2.drawLine(r+r/5+cx+1,y,r+r/5+cx+ticklen,y);
//				label=String.valueOf(i);
				w=fm.stringWidth(" ");
//				g2.drawString(label,r+r/5+cx+ticklen+w,y+h/2);
				y+=4*r/3/n;
				i-=180/n;				
			}
			y=y_ini; i=0;
			while (y>r/3+cy) {
				g2.drawLine(r+r/5+cx+1,y,r+r/5+cx+ticklen,y);
//				label=String.valueOf(i);
				w=fm.stringWidth(" -");
//				g2.drawString(label,r+r/5+cx+ticklen+w,y+h/2);
				y-=4*r/3/n;
				i+=180/n;
//				System.out.println("two\n");
			}
		}
		else
		{
			//for upside-down flight pitch
//			pitch=(pitch>90)?pitch-180:pitch+180;
//			g2.setColor(new Color(0x666600));
//			g2.fillRect(r-r/5+cx,r/3+cy,r*2/5,r+2*r*pitch/90/3-r/3);
//			g2.setColor(new Color(0x9999FF));
//			g2.fillRect(r-r/5+cx,r+2*r*pitch/90/3+cy,r*2/5,r-2*r*pitch/90/3-r/3);
		}			
	}
	
	
	public void paint(Graphics g) {
		super.paint(g);
//		System.out.println("Paint..\n");
		this.draw(g);
		//Toolkit.getDefaultToolkit().sync();
	}

	/*	protected void drawBack()
	{
//		 initialize buffer
		Graphics dbg;
		if (dbImage == null) 
		{ 
		dbImage = createImage (this.getSize().width, this.getSize().height); 
		} 
		dbg = dbImage.getGraphics (); 
//		 clear screen in background 
		dbg.setColor (getBackground ()); 
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); 

//		 draw elements in background 
		dbg.setColor (getForeground()); 
		paint (dbg); 
	}
*/	
	public void messageEvent(DownlinkMessageEvent ev) {
		Message m = ev.getMessage();
		//process only downlink messages id=6 from currect AC
		if (m.msgClass()!=0 || m.id()!=6 || m.acRec().get_id()!=ac) return; 
		set((int)MathFP.toLong(m.getFields().get(0)[0]),
			(int)MathFP.toLong(m.getFields().get(2)[0]),0,0);
	}

	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource().getClass()==AcInfoContainer.class)
			this.ac=((AcInfoContainer) arg0.getSource()).getSelected();		
	}

//	@Override
	public boolean isOpaque() {
		return false;
	}
	
	
}
